package by.sjc.giz.web.controller;


import by.sjc.giz.model.Account;
import by.sjc.giz.model.Book;
import by.sjc.giz.model.BooksFilter;
import by.sjc.giz.model.Subject;
import by.sjc.giz.model.shop.BookInShop;
import by.sjc.giz.model.shop.BookInShopListWrapper;
import by.sjc.giz.model.shop.BooksWithMaxCount;
import by.sjc.giz.security.CustomUserDetails;
import by.sjc.giz.service.AccountService;
import by.sjc.giz.service.BookService;
import by.sjc.giz.service.ShopService;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.List;

/**
 * Created by irina on 10.08.14.
 */

@Controller
@RequestMapping("/shop")
public class ShopController {

    public static final Logger logger = Logger.getLogger(ShopController.class);

    @Autowired
    private ShopService shopService;
    @Autowired
    private AccountService accountService;
    @Autowired
    private BookService bookService;

    @RequestMapping (value = {"/list","/"})
    public ModelAndView shops() {

        logger.debug("shop list");
        ModelAndView mav = new ModelAndView();
        mav.addObject("shops", shopService.shops());
        mav.setViewName("shop.list");
        return mav;
    }

    @PreAuthorize("#shop.type.value=='SHOP'")
    @RequestMapping(value = {"/{id}"})
    public ModelAndView shopInfo(@PathVariable("id") Subject shop) {

        ModelAndView mav = new ModelAndView();
        mav.setViewName("shop.info");
        mav.addObject(shop);
        return mav;
    }

    @PreAuthorize("isFullyAuthenticated() and principal.account.subject.type.value=='SHOP'")
    @RequestMapping(value = {"/admin"})
    public ModelAndView shopAdmin(Authentication authentication) {
        Subject shop = ((CustomUserDetails) authentication.getPrincipal()).getAccount().getSubject();

        ModelAndView mav = new ModelAndView();
        mav.setViewName("shop.admin");
        mav.addObject(shop);
        return mav;
    }

    @PreAuthorize("isFullyAuthenticated() and principal.account.subject.type.value=='SHOP'")
    @RequestMapping(value = {"/books/add"})
    public ModelAndView addBook(Authentication authentication) {
        Subject shop = ((CustomUserDetails) authentication.getPrincipal()).getAccount().getSubject();

        ModelAndView mav = new ModelAndView();
        mav.setViewName("shop.books.add");
        mav.addObject(shop);
        return mav;
    }

    @PreAuthorize("isFullyAuthenticated() and principal.account.subject.type.value=='SHOP'")
    @RequestMapping(value = {"/employees"})
    public ModelAndView employees(Authentication authentication) {
        Subject shop = ((CustomUserDetails) authentication.getPrincipal()).getAccount().getSubject();

        List<Account> employeesList = accountService.getSubjectAccounts(shop.getId());
        ModelAndView mav = new ModelAndView();
        mav.setViewName("employeesList");
        mav.addObject("employees", employeesList);
        mav.addObject("employer", shop);
        return mav;
    }

    @PreAuthorize("isFullyAuthenticated() and principal.account.subject.type.value=='SHOP'")
    @RequestMapping(value = {"/admin/genres/profitable"})
    public ModelAndView listProfitableGenres(Authentication authentication) {
        Subject shop = ((CustomUserDetails) authentication.getPrincipal()).getAccount().getSubject();

        ModelAndView mav = new ModelAndView();
        List<String> genres = shopService.getProfitableGenres(shop.getId());
        mav.setViewName("book.genres");
        mav.addObject("genres", genres);
        return mav;
    }


    @PreAuthorize("#shop.type.value=='SHOP'")
    @RequestMapping(value = {"/{id}/books"})
    public ModelAndView listShopBooks(
            @PathVariable("id") Subject shop,
            @RequestParam(value = "pageNum",defaultValue = "1") int pageNum,
            @RequestParam(value = "pageSize",defaultValue = "5") int pageSize,
            BooksFilter filter ) {
        logger.info("filter by shop="+shop);

        if (filter==null)
            filter = new BooksFilter();
        filter.setShop(shop.getName());

        BooksWithMaxCount res = shopService.getBooks(pageSize,pageNum,filter);

        List<String> allGenres = bookService.getAllGenres();
        List<String> allAuthors = bookService.getAllAuthors();
        List<String> allPublishers = bookService.getAllPublishers();

        ModelAndView mav = new ModelAndView();
        mav.setViewName("shop.books");

        mav.addObject("books",res.getBooks());

        mav.addObject("shop", shop);
        mav.addObject("allGenres",allGenres);
        mav.addObject("allAuthors",allAuthors);
        mav.addObject("allPublishers",allPublishers);

        mav.addObject("filter",filter);

        mav.addObject("pageCount", res.getPageCount(pageSize));
        mav.addObject("pageNum",pageNum);
        mav.addObject("pageSize",pageSize);

        return mav;
    }


    @RequestMapping(value = {"/books"})
    public ModelAndView listAllBooks(
            @RequestParam(value = "pageNum", defaultValue = "1") int pageNum,
            @RequestParam(value = "pageSize", defaultValue = "5") int pageSize,
            BooksFilter filter ) {

        if (filter == null)
            filter = new BooksFilter();
        logger.info("filter : " + filter);

        BooksWithMaxCount res = shopService.getBooks(pageSize, pageNum, filter);

        List<String> allGenres = bookService.getAllGenres();
        List<String> allAuthors = bookService.getAllAuthors();
        List<String> allPublishers = bookService.getAllPublishers();
        List<String> allShops = bookService.getAllShops();

        ModelAndView mav = new ModelAndView();
        mav.setViewName("shop.books");

        mav.addObject("books", res.getBooks());

        mav.addObject("allGenres", allGenres);
        mav.addObject("allAuthors", allAuthors);
        mav.addObject("allPublishers", allPublishers);
        mav.addObject("allShops", allShops);

        mav.addObject("filter", filter);

        mav.addObject("pageCount", res.getPageCount(pageSize));
        mav.addObject("pageNum", pageNum);
        mav.addObject("pageSize", pageSize);

        return mav;
    }

    @PreAuthorize("isFullyAuthenticated() and principal.account.subject.type.value=='SHOP'")
    @RequestMapping(value = {"/books/price"}, method = {RequestMethod.POST})
    public ModelAndView booksPrice(
            @ModelAttribute("books") BookInShopListWrapper books,
            Authentication authentication) {
        Subject shop = ((CustomUserDetails) authentication.getPrincipal()).getAccount().getSubject();

        ModelAndView mav = new ModelAndView();

        for (BookInShop bookInShop : books.getBookInShopList()) {
            Book book = bookService.getBookById(bookInShop.getBook().getId());
            bookInShop.setBook(book);
            bookInShop.setShop(shop);
        }
        shopService.addBooksToStore(books.getBookInShopList());
        mav.setViewName("redirect:/shop/" + shop.getId() + "/books");

        return mav;
    }

    @PreAuthorize("isFullyAuthenticated() and principal.account.subject.type.value=='SHOP'")
    @RequestMapping(value = { "/profit" }, method = { RequestMethod.GET })
    public ModelAndView profit(Authentication authentication) {
        Subject shop = ((CustomUserDetails) authentication.getPrincipal()).getAccount().getSubject();

        ModelAndView mav = new ModelAndView();

        mav.setViewName("shop.profit");
        mav.addObject("min", shopService.getDateOfFirstOrder(shop.getId()));
        mav.addObject("max", shopService.getDateOfLastOrder(shop.getId()));

        return  mav;
    }

    @PreAuthorize("isFullyAuthenticated() and principal.account.subject.type.value=='SHOP'")
    @RequestMapping(value="/profit/show")
    @ResponseBody
    public float showProfit(
            @RequestParam("startDate") String startDate,
            @RequestParam("endDate") String endDate,
            Authentication authentication) throws ParseException {
        Subject shop = ((CustomUserDetails) authentication.getPrincipal()).getAccount().getSubject();

        DateFormat f = new SimpleDateFormat("yyyy-MM-dd");
        return shopService.getProfit(shop.getId(), f.parse(startDate), f.parse(endDate));
    }

    @PreAuthorize("isFullyAuthenticated() and principal.account.subject.id == #shopId")
    @RequestMapping(value="/book/price/change", method = { RequestMethod.POST } )
    @ResponseBody
    public float changeBookPrice(
            @RequestParam("price") float price,
            @RequestParam("bookId") int bookId,
            @RequestParam("shopId") int shopId) throws ParseException {

        BookInShop bookInShop = shopService.getBookInShop(bookId, shopId);
        logger.info("BOOK: " + bookInShop + "book " + bookInShop.getBook());
        bookInShop.setSellPrice(price);

        shopService.updateBookInShop(bookInShop);
        return price;
    }
}
